package com.xbongbong.pro.message.listener;/*/*/

import com.alibaba.dingtalk.openapi.newmessage.helper.CorpConversationHelper;
import com.alibaba.fastjson.JSONArray;

import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.service.MessageNewService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * 消息状态查询 轮询
 * @author 魏荣杰
 * @date 2019/4/2 17:04
 * @since v1.0
 * @version v1.0
 */
@WebListener
public class MessageResultContextListener implements ServletContextListener {
    private static final Logger LOG = LoggerFactory.getLogger(MessageResultContextListener.class);

    private static ScheduledExecutorService executorLoop = null;

    private PushModel pushModel;
    private MessageNewService messageNewService;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        ApplicationContext ctx = WebApplicationContextUtils
                .getWebApplicationContext(context);
        pushModel = (PushModel) ctx.getBean("pushModel");
        messageNewService = (MessageNewService) ctx.getBean("messageNewService");
        try {
            LOG.info(DateUtil.getString() + " MessageResultContextListener start");
            loop();
        } catch (Exception e) {
            LOG.error("MessageResultContextListener 启动失败", e);
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        try {
            loopClose();
        } catch (Exception e) {
            LOG.error("MessageResultContextListener 停止失败", e);
        }
    }

    private void loop() {
        Runnable runnable = () -> {
            Integer now = DateUtil.getInt();
            Integer startPushTime = DateUtil.getTodayInt() - 60;
            //查询半5分钟前推送过的消息
            Integer endPushTime = now - 300;
            Map<String, Object> param = new HashMap<>(16);
            param.put("startPushTime", startPushTime);
            param.put("endPushTime", endPushTime);
            param.put("isPush", 1);
            param.put("del", 0);
            param.put("status", 0);
            param.put("start", 0);
            param.put("pageNum", 500);
            List<PushEntity> pushEntityList;
            try {
                pushEntityList = pushModel.findEntitys(param);
            } catch (Exception e) {
                pushEntityList = new ArrayList<>();
                LOG.error("轮询消息发送结果查询时查询push数据，数据库查询失败", e);
            }

            LOG.info(DateUtil.getString() + "MessageResultContextListener pushList.size:"+pushEntityList.size());
            for (PushEntity pushEntity : pushEntityList) {
                Long taskId = pushEntity.getTaskId();
                String corpid = pushEntity.getCorpid();

                if (taskId != null && taskId > 0) {
                    CorpConversationHelper.SendResultResponse sendResultResponse;
                    try {
                        sendResultResponse = messageNewService.dingtalkOAMessagePushSendResult(corpid, taskId);
                        if (sendResultResponse != null) {
                            CorpConversationHelper.SendResultResponse.SendResult sendResult = sendResultResponse.getSendResult();
                            if (sendResult != null) {
                                String forbiddenUserIdList = sendResult.getForbiddenUserIdList();
                                List<String> forbiddenUserIds = new ArrayList<>();
                                if (forbiddenUserIdList != null) {
                                    forbiddenUserIds = JSONArray.parseArray(forbiddenUserIdList, String.class);
                                }
                                boolean forbiden = forbiddenUserIds != null && forbiddenUserIds.size() > 0;

                                String unreadUserIdList = sendResult.getUnreadUserIdList();
                                List<String> unreadUserIds = new ArrayList<>();
                                if (unreadUserIdList != null) {
                                    unreadUserIds = JSONArray.parseArray(unreadUserIdList, String.class);
                                }
                                boolean unread = unreadUserIds != null && unreadUserIds.size() > 0;

                                String readUserIdList = sendResult.getReadUserIdList();
                                List<String> readUserIds = new ArrayList<>();
                                if (readUserIdList != null) {
                                    readUserIds = JSONArray.parseArray(readUserIdList, String.class);
                                }
                                boolean read = readUserIds != null && readUserIds.size() > 0;

                                //有推送成功用户标志
                                boolean success = unread || read;
                                if (!forbiden && success) {
                                    //全部成功
                                    pushEntity.setStatus(3);
                                }
                                if (forbiden && success) {
                                    //部分成功
                                    pushEntity.setStatus(2);
                                }
                                if (forbiden && !success) {
                                    //全部失败
                                    pushEntity.setStatus(1);
                                }
                                if (!forbiden && !success) {
                                    //无效推送对象
                                    pushEntity.setStatus(4);
                                }
                            } else {
                                //查询钉钉没结果
                                pushEntity.setStatus(5);
                            }
                        } else {
                            //查询钉钉没结果
                            pushEntity.setStatus(5);
                        }
                    } catch (XbbException e) {
                        //只有获取accessToken或agentId失败才会有这错
//                            pushEntity.setDel(3);
                        pushEntity.setStatus(5);
                    } catch (Exception e) {
                        //未知错误
                        pushEntity.setStatus(5);
                        LOG.error(" dingtalkOAMessagePushSendResult Exception e=============", e);
                    }

                    try {
                        pushModel.save(pushEntity);
                    } catch (Exception e) {
                        LOG.error("数据库操作失败", e);
                        continue;
                    }

                }

            }

        };

        if (executorLoop == null || executorLoop.isShutdown() || executorLoop.isTerminated()) {
            executorLoop = Executors.newScheduledThreadPool(5);
            LOG.info(DateUtil.getString() + "MessageResult loop start");
            executorLoop.scheduleWithFixedDelay(runnable,0, 5000, TimeUnit.MILLISECONDS);
        }
    }

    private void loopClose() {
        LOG.info(DateUtil.getString() + "MessageResult loop stop");
        executorLoop.shutdown();
        executorLoop = null;
    }
}
